package server

import (
	"log"
	"net"
	"strconv"
	"strings"
)

func TcpConnectHandler(conn *net.TCPConn) {
	var httpBody string
	var httpSize int
	addr := conn.RemoteAddr()
	ip, port, err := net.SplitHostPort(addr.String())
	if err != nil {
		return
	}
	//读取一次完整的http报文
	for {
		var readBuf = make([]byte, 1024)
		readLen, err := conn.Read(readBuf)
		if err != nil {
			log.Println("conn closed")
			return
		}
		httpBody += string(readBuf[:readLen])
		httpSize += readLen
		if (readBuf[readLen-1] == '\n') && readLen < 1024 {
			break
		}
	}
	//log.Println(httpBody, httpSize)
	req := onceHttpBodySynx(httpBody)
	var res Response = &MyResponse{}
	//通过path请求地址找到对应的业务处理函数
	var message string
	var code string
	controller := PathRoute(req.Path, req.Method)
	if controller == nil {
		message = "not found"
		code = "404"
	} else {
		message = controller(req, res)
		code = res.GetCode()
		if code == "" {
			code = "200"
		}
	}
	buildFinalHttpResponse(message, code, res)
	//作业点3 记录访问日志 客户端ip，http返回码
	log.Println("client ip " + ip + ":" + port + ",访问服务地址->" + req.Path + ",响应status code =" + code)
	httpStr := res.ToHttpStr()

	n, err := conn.Write([]byte(httpStr))
	if err != nil {
		log.Println("failed to write response contents")
	}
	log.Println("send response data " + strconv.Itoa(n))
	conn.Close()
}

func buildFinalHttpResponse(message string, code string, res Response) {
	//构建response对象
	//var res Response = &MyResponse{}
	res.Write(message)
	res.Code(code)
	res.SetContextType("text/html;charset=utf-8")
	res.AddHead("Content-Length", strconv.Itoa(len(message)))
}


func onceHttpBodySynx(httpBody string) Request {
	req := Request{}
	var headers []Header
	//按照换行符解析httpBody
	split := strings.Split(httpBody, "\n")
	for _, line := range split {
		log.Println("synx:" + line)
		line = strings.TrimRight(line, "\r")
		if line == "" {
			continue
		}
		if !strings.Contains(line, ":") {
			//GET / HTTP/1.1
			split := strings.Split(line, " ")
			req.Method = strings.TrimSpace(split[0])
			req.Path = split[1]
			req.Protocol = strings.TrimSpace(split[2])
		} else {
			//剩下的大部分都属于头信息
			keyValue := strings.SplitN(line, ":", 2)
			header := Header{Key: keyValue[0], Value: keyValue[1]}
			headers = append(headers, header)
		}
	}
	req.Headers = headers
	return req
}
